package com.baozun.controller;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

import com.baozun.model.TAppendix;
import com.baozun.model.TAppendixExample;
import com.baozun.model.TUser;
import com.baozun.model.TWorkrecord;
import com.baozun.model.TWorkrecordExample;
import com.baozun.service.AppendixService;
import com.baozun.service.WorkrecordService;
import com.baozun.util.AjaxUtil;
import com.baozun.util.CommonConst;
import com.baozun.util.DataEncapsulation;
import com.baozun.util.FileUtil;
import com.baozun.util.MD5Util;
import com.baozun.util.ModelAndViewUtil;
import com.baozun.util.ModelMapUtil;
import com.baozun.util.PageData;
import com.baozun.util.ReloadablePropertiesUtil;
import com.baozun.util.StringUtil;
import com.baozun.util.WebUtil;

/**
 * 
 * @Title:
 * @Company:宝尊电子商务有限公司
 * @Description:
 * @Author:xiaozhou.zhou
 * @Since:2015年1月23日
 * @Copyright:Copyright (c) 2014
 * @ModifyDate:
 * @Version:1.1.0
 */
@Controller
@RequestMapping("/work")
public class WorkrecordController {

    @Autowired
    @Qualifier("workrecordService")
    private WorkrecordService workrecordService;
    @Autowired
    @Qualifier("appendixService")
    private AppendixService appendixService;

    @Autowired
    @Qualifier("workrecordCongifService")
    private ReloadablePropertiesUtil workrecordCongifService;

    /**
     * 日志内容中的图片的识别正则表达式，摘自网上
     */
    private String imageRegex = "<\\s*img\\s+([^>]+)\\s*>";

    /**
     * 主界面
     * 
     * @param request
     * @param response
     * @return
     * @Description:
     */
    @RequestMapping("/workrecord_main")
    public ModelAndView workrecordMain(HttpServletRequest request, HttpServletResponse response) {
        return new ModelAndView("work/workrecord_main");
    }

    /**
     * 列表界面
     * 
     * @param request
     * @param response
     * @return
     * @Description:
     */
    @RequestMapping("/workrecord_list")
    public ModelAndView workrecordList(HttpServletRequest request, HttpServletResponse response) {
        String pageSizeStr = request.getParameter("pageSize");
        String currentPageStr = request.getParameter("currentPage");
        String stTitle = request.getParameter("title");
        String stType = request.getParameter("type");
        
        int pageSize = StringUtil.getIntFromStr(pageSizeStr, 20);
        int currentPage = StringUtil.getIntFromStr(currentPageStr, 1);
        TUser user = (TUser) request.getSession().getAttribute(CommonConst.SESSION_USER);
        String stUserId = user.getStUserId();

        // 得到条件
        TWorkrecordExample record = new TWorkrecordExample();
        TWorkrecordExample.Criteria criteria = record.createCriteria();
        criteria.andStUserIdEqualTo(stUserId);
        if (StringUtils.isNotEmpty(stTitle)) {
            criteria.andStTitleLike("%"+ stTitle+"%");
        }
        if(StringUtils.isNotEmpty(stType)){
            criteria.andStTypeEqualTo(stType);
        }
        // 排序
        String order = TWorkrecord.DT_CREATE_TIME + " DESC";
        record.setOrderByClause(order);
        PageData<TWorkrecord> infoList = workrecordService.getPageListByExample(record, pageSize, currentPage);
        return new ModelAndViewUtil().setModel(CommonConst.REQUEST_WORKRECORD_LIST, infoList).toUrl("work/workrecord_list");
    }

    @RequestMapping("/workrecord_add")
    public ModelAndView workrecordAdd(HttpServletRequest request, HttpServletResponse response) {
        return new ModelAndViewUtil().toUrl("work/workrecord_add");
    }

    /**
     * 带图片处理机制,文件验证（md5验证重复性）
     * 
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/workrecord_add_submit")
    public String workrecordAddSubmit(ModelMap model, HttpServletRequest request, HttpServletResponse response, @RequestParam MultipartFile[] files) {
        response.setContentType("text/plain");
        TUser user = (TUser) request.getSession().getAttribute(CommonConst.SESSION_USER);
        String stWorkrecordId = request.getParameter("stWorkrecordId");
        boolean isExist = true;
        try {
            if(StringUtils.isEmpty(stWorkrecordId)){
                isExist = false;
            }
            // 日志其它参数保存
            TWorkrecord workrecord = DataEncapsulation.request2Bean(request, TWorkrecord.class);
            // 处理附件
            saveAppend(request, files, workrecord);
            // 对文档中图片进行验证
            workrecord.setClContent(getClContent(request, user.getStUserId(), workrecord.getClContent()));
            if(isExist){
                workrecordService.update(workrecord);
            }else{
                workrecordService.add(workrecord);
            }
        } catch (Exception e) {
            e.printStackTrace();
            new ModelMapUtil(model).put("message", "新增失败");
        }
        return UrlBasedViewResolver.REDIRECT_URL_PREFIX + "workrecord_list";
    }
    
    @RequestMapping("workrecord_quick_save_submit")
    public String workrecordQuickSaveSubmit(ModelMap model, HttpServletRequest request, HttpServletResponse response, @RequestParam MultipartFile[] files) {
        TUser user = (TUser) request.getSession().getAttribute(CommonConst.SESSION_USER);
        String stWorkrecordId = request.getParameter("stWorkrecordId");
        boolean isExist = true;
        try {
            // 日志其它参数保存
            TWorkrecord workrecord = DataEncapsulation.request2Bean(request, TWorkrecord.class);
            if(StringUtils.isEmpty(stWorkrecordId)){
                stWorkrecordId = UUID.randomUUID().toString();
                isExist =false;
            }
            // 处理附件
            saveAppend(request, files, workrecord);
            // 对文档中图片进行验证
            workrecord.setClContent(getClContent(request, user.getStUserId(), workrecord.getClContent()));
            if(isExist){
                workrecordService.update(workrecord);
            }else{
                workrecordService.add(workrecord);
            }
        } catch (Exception e) {
            e.printStackTrace();
            new ModelMapUtil(model).put("message", "保存失败");
        }
        
        new ModelMapUtil(model).put("msg", WebUtil.encodeURL("保存成功！")).put("jsm", "quickId('"+stWorkrecordId+"')");
        return "include/refresh";
    }
    /**
     * 进入编辑界面
     * 
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/workrecord_edit")
    public ModelAndView workrecordEdit(HttpServletRequest request, HttpServletResponse response) {
        String stWorkrecordId = request.getParameter("stWorkrecordId");
        TWorkrecord workrecord = workrecordService.get(stWorkrecordId);
        // 得到日志中的附件列表
        TAppendixExample record = new TAppendixExample();
        TAppendixExample.Criteria criteria = record.createCriteria();
        criteria.andStFkIdEqualTo(stWorkrecordId);
        String order = TAppendix.DT_CREATE_TIME + " DESC";
        record.setOrderByClause(order);
        List<TAppendix> appendixList = appendixService.getList(record);
        return new ModelAndViewUtil().setModel("appendixList", appendixList).setModel(TWorkrecord.T_WORKRECORD, workrecord).toUrl("work/workrecord_edit");
    }

    /**
     * 编辑提交
     * 
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/workrecord_edit_submit")
    public String workrecordEditSubmit(ModelMap model, HttpServletRequest request, HttpServletResponse response, @RequestParam MultipartFile[] files) {
        try {
            TWorkrecord workrecord = DataEncapsulation.request2Bean(request, TWorkrecord.class);
            TUser user = (TUser) request.getSession().getAttribute(CommonConst.SESSION_USER);
            // 得到要清除的附件ID定义为id1,id2,id3
            String stAppendixIdArrayStr = request.getParameter("remove_appendix_id_array");
            if (StringUtils.isNotEmpty(stAppendixIdArrayStr)) {
                String[] stAppendixIdArray = stAppendixIdArrayStr.split(",");
                TAppendixExample record = new TAppendixExample();
                record.createCriteria().andStAppendixIdIn(Arrays.asList(stAppendixIdArray));
                List<TAppendix> appendixList = appendixService.getList(record);
                deleteAppendixs(request, appendixList);
            }
            // 对附件进行处理
            saveAppend(request, files, workrecord);
            // 处理内容中图片
            workrecord.setClContent(getClContent(request, user.getStUserId(), workrecord.getClContent()));
            workrecordService.update(workrecord);
        } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            // 将消息传递到list界面
            new ModelMapUtil(model).put("message", "修改失败");
        }
        return UrlBasedViewResolver.REDIRECT_URL_PREFIX + "workrecord_list";

    }

    /**
     * 删除工作日志
     * 
     * @param request
     * @param response
     */
    @RequestMapping("/workrecord_delete")
    public void workrecordDelete(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter out = AjaxUtil.getWriter(request, response);
        try {
            String stWorkrecordId = request.getParameter(TWorkrecord.ST_WORKRECORD_ID);
            TWorkrecord workrecord = workrecordService.get(stWorkrecordId);
            // 得到所有的附件信息并进行删除
            TAppendixExample record = new TAppendixExample();
            record.createCriteria().andStFkIdEqualTo(stWorkrecordId);
            List<TAppendix> appendixList = appendixService.getList(record);
            // 删除文件数据以及文件
            deleteAppendixs(request, appendixList);
            // 得到图片信息
            List<String> imgList = StringUtil.absPattern(workrecord.getClContent(), imageRegex);
            String systemPath = request.getSession().getServletContext().getRealPath("/");
            if (!CollectionUtils.isEmpty(imgList)) {
                for (String img : imgList) {
                    // 得到图片文件，进行删除
                    String src = img.substring(img.indexOf("src") + 5);
                    src = src.substring(0, src.indexOf("\""));
                    FileUtil.deleteFile(systemPath + src);
                }
            }
            workrecordService.delete(stWorkrecordId);
            out.print(CommonConst.AJAX_RIGHT);
        } catch (Exception e) {
            out.print(CommonConst.AJAX_ERROR);
            e.printStackTrace();
        }
        out.flush();
        out.close();
    }

    /**
     * @param request
     * @param stUserId
     * @param content
     * @return
     * 
     */
    private String getClContent(HttpServletRequest request, String stUserId, String content) {
        String systemPath = request.getSession().getServletContext().getRealPath("/");
        // 图片暂存路径
        String tempPath = workrecordCongifService.loadString("temp.path");
        try {
            // 根据图片中信息得到map,,XXXXXXXX<img src="xxx/xxx/xxx.jpg" xxxxxxxx/>XXXXXxxxx<img
            // src="(base64编码)"
            // xxxxxxxx/>
            List<String> itemStrList = StringUtil.absPattern(content, imageRegex);
            if (!CollectionUtils.isEmpty(itemStrList)) {
                for (String str : itemStrList) {
                    // if (str.indexOf("data-ke-src") > -1) {
                    // // 去掉内容中的data-ke-src内容
                    // String head = str.substring(0, str.indexOf("data-ke-src"));
                    // String body = str.substring(str.indexOf("data-ke-src") + 14);
                    // String end = body.substring(body.indexOf("\""));
                    // str = head + end;
                    // 解析每个图片字符串
                    String src = str.substring(str.indexOf("src") + 5);
                    src = src.substring(0, src.indexOf("\""));

                    // 如果src中包含了base64编码字符串
                    if (src.indexOf("data:image") > -1 && src.indexOf(";base64") > -1) {
                        // /得到base64字符串
                        String prefix = src.substring(src.indexOf("/") + 1, src.indexOf(";base64"));
                        String base64 = src.substring(src.indexOf(";base64,") + 8);
                        String path = "user/photo/workrecord/" + stUserId;
                        String fileName = UUID.randomUUID().toString() + "." + prefix;
                        // 先得到暂存文件
                        File file = FileUtil.base64ToFile(systemPath + tempPath, fileName, base64);
                        // 如果该文件的md5在图片库中存在，将路径进行更换（标准为该用户的同一种类型，见CommonConst.FILE_TYPE_*）
                        String MD5 = MD5Util.getFileMD5String(file);
                        // 如果photoList不为空，则使用查询出来的代替该地址
                        String imageSrc = "";
                        File[] files = new File(systemPath + path).listFiles();
                        boolean isExistThisFile = false;
                        // 得到文件列表不为空进行检索
                        if (files != null) {
                            for (File singleFile : files) {
                                String singleMd5 = MD5Util.getFileMD5String(singleFile);
                                if (MD5.equals(singleMd5)) {
                                    isExistThisFile = true;
                                    // 将已经存在的文件名赋值给fileName
                                    fileName = singleFile.getName();
                                }
                            }
                        }
                        if (isExistThisFile) {
                            // 存在该图片，只需要删除该缓存文件即可
                            FileUtil.deleteFile(file);
                        } else {
                            // 不存在相同md5文件的话
                            FileUtil.copyFile(file, systemPath + path, fileName, true);
                        }
                        // 由于是从根目录搜索到用户图片的，所以前面需要加上../
                        imageSrc = "../" + path + "/" + fileName;
                        content = content.replace(src, imageSrc);
                    }
                    // }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }

    /**
     * 附件的处理，带md5验证
     * 
     * @param request
     * @param files
     * @param workrecord
     * @Description:
     */
    private void saveAppend(HttpServletRequest request, MultipartFile[] files, TWorkrecord workrecord) {
        String systemPath = request.getSession().getServletContext().getRealPath("/");// 得到的是系统目录
        if (files != null) {
            for (MultipartFile file : files) {
                if (!file.isEmpty()) {
                    String fileName = file.getOriginalFilename();// 得到的是上传时候的文件名
                    String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);// 得到扩展名
                    long fileSize = file.getSize();
                    String appendixPath = "user/file/" + workrecord.getStUserId() + "/";
                    String createFileName = UUID.randomUUID().toString() + "." + suffix;
                    // 将流写入文件
                    File temp;
                    try {
                        temp = FileUtil.stream2File(file.getInputStream(), systemPath + appendixPath, createFileName);
                        // 生成文件
                        String md5 = MD5Util.getFileMD5String(temp);
                        // 将数据保存进附件表中
                        TAppendix appendix = new TAppendix();
                        appendix.setStFkId(workrecord.getStWorkrecordId());
                        appendix.setDtCreateTime(new Date());
                        appendix.setStAppendixAddress("../" + appendixPath + createFileName);
                        appendix.setStFileName(fileName);
                        appendix.setStFileSuffix(suffix);
                        appendix.setStFileSize(fileSize);
                        appendix.setStFileType(suffix);
                        appendix.setStAppendixMd5(md5);
                        appendixService.add(appendix);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        }
    }

    /**
     * 删除附件数据和附件
     * 
     * @param request
     * @param appendixList
     * @Description:
     */
    private void deleteAppendixs(HttpServletRequest request, List<TAppendix> appendixList) {
        for (TAppendix appendix : appendixList) {
            deleteAppendix(request, appendix);
        }
    }
    
    private void deleteAppendix(HttpServletRequest request, TAppendix appendix){
        String stAppendixAddress = appendix.getStAppendixAddress();
        stAppendixAddress = stAppendixAddress.replace("../", "");
        // 删除附件
        String systemPath = request.getSession().getServletContext().getRealPath("/");
        FileUtil.deleteFile(systemPath + stAppendixAddress);
        appendixService.delete(appendix.getStAppendixId());
    }
}
